home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Containers / ActiveXApp / CActiveXView.cpp < prev    next >
Encoding:
Text File  |  1996-12-21  |  28.9 KB  |  1,091 lines  |  [TEXT/CWIE]

  1. // ===========================================================================
  2. //    CActiveXView.cpp               ©1996 Microsoft Corporation. All rights reserved.
  3. // ===========================================================================
  4. //
  5. //    manages an active x control
  6.  
  7. #ifdef PowerPlant_PCH
  8. #include PowerPlant_PCH
  9. #endif
  10.  
  11. #include "ActiveXAppConstants.h"
  12. #include "CActiveXDocument.h"
  13. #include "CActiveXView.h"
  14. #include "CActiveXPeriodical.h"
  15. #include "CArgumentParser.h"
  16. #include <LArray.h>
  17. #include <LStream.h>
  18. #include <UDrawingState.h>
  19. #ifdef MULTI_CONTEXT_TEST_APP
  20. #include "CActiveXShadowView.h"
  21. #endif    //    MULTI_CONTEXT_TEST_APP
  22. #include "Util.h"
  23.  
  24. #ifndef __TOOLUTILS__
  25. #include <ToolUtils.h>
  26. #endif
  27.  
  28. #include "HEADERS.H"
  29. #include "CIdle.h"
  30.  
  31. static void CToPString(Char8* CPtr, StringPtr PStr);
  32.  
  33. #pragma mark === CActiveXView::Construction & Destruction ===
  34.  
  35. // ---------------------------------------------------------------------------
  36. //        • CActiveXView::CreateActiveXViewStream [static]
  37. // ---------------------------------------------------------------------------
  38. //    Return a new active x object initialized using data from a Stream
  39.  
  40. CActiveXView*
  41. CActiveXView::CreateActiveXViewStream(
  42.     LStream    *inStream)
  43. {
  44.     return (new CActiveXView(inStream));
  45. }
  46.  
  47.  
  48. // ---------------------------------------------------------------------------
  49. //        • CActiveXView::CActiveXView
  50. // ---------------------------------------------------------------------------
  51. //    Default Constructor
  52.  
  53. CActiveXView::CActiveXView() : LDragAndDrop(UQDGlobals::GetCurrentPort(), this)
  54. {
  55.     CommonInit();
  56. }
  57.  
  58.  
  59. // ---------------------------------------------------------------------------
  60. //        • CActiveXView::CActiveXView(LStream*)
  61. // ---------------------------------------------------------------------------
  62. //    Construct control from the data in a Stream
  63.  
  64. CActiveXView::CActiveXView(LStream    *inStream)
  65.         : LView(inStream), LDragAndDrop(UQDGlobals::GetCurrentPort(), this)
  66. {
  67.     CArgumentParser    Parser;
  68.     Char8            **ArgNames;
  69.     Char8            **ArgValues;
  70.     Int16            ArgCount;
  71.     Ptr                ArgBufferP;
  72.     Uchar8            CharCount;
  73.  
  74.     CommonInit();
  75.  
  76.     inStream->ReadData(&CharCount, sizeof(Uchar8));
  77.     while (CharCount--)
  78.     {
  79.         Char8    Char;
  80.         inStream->ReadData(&Char, sizeof(Char8));
  81.         Parser.ProcessChar(Char);
  82.     }
  83.     Parser.ProcessChar('\0');    //    tell the parser the stream is done
  84.  
  85.     Parser.GetArguments(&ArgBufferP,&ArgNames, &ArgValues, &ArgCount);
  86.  
  87.     if (ArgCount)
  88.         InstantiateControl(ArgNames, ArgValues, ArgCount);
  89.  
  90.     if (ArgBufferP)
  91.         ::DisposePtr(ArgBufferP);
  92. }
  93.  
  94.  
  95. // ---------------------------------------------------------------------------
  96. //        • CActiveXView::~CActiveXView()
  97. // ---------------------------------------------------------------------------
  98. //    Destructor
  99.  
  100. CActiveXView::~CActiveXView(void)
  101. {
  102.     RemoveControl();
  103.     while (mViewArrayP && mViewArrayP->GetCount())
  104.     {
  105.         LView    *theView;
  106.         mViewArrayP->FetchItemAt(1, (void*)&theView);
  107. #ifdef MULTI_CONTEXT_TEST_APP
  108.         if (theView != this)
  109.             ((CActiveXShadowView*)theView)->SetMasterView(NULL);
  110. #endif    //    MULTI_CONTEXT_TEST_APP
  111.         mViewArrayP->RemoveItemsAt(1,1);
  112.     }
  113.     delete mViewArrayP;
  114.     mViewArrayP = NULL;
  115. }
  116.  
  117.  
  118. #pragma mark === CActiveXView ===
  119.  
  120. // ---------------------------------------------------------------------------
  121. //        • CActiveXView::CommonInit
  122. // ---------------------------------------------------------------------------
  123. //    do common initialization of the view
  124.  
  125. void
  126. CActiveXView::CommonInit(void)
  127. {
  128.     Boolean8    FalseBool = false;
  129.  
  130.     mStreamIdleP = NULL;
  131.     mMouseUpAttachmentP = NULL;
  132.     mDocumentP = CActiveXDocument::GetDefaultContainer();
  133.     mViewArrayP = new LArray(sizeof(LView *));
  134.     mViewArrayP->InsertItemsAt(1, 1, (void*)&this);
  135.     mPendingViewsP = NULL;
  136.     mActiveView = this;
  137.     mInRequestFocus = false;
  138.     mContextDirty = false;
  139.     mDirty = false;
  140. }
  141.  
  142.  
  143. // ---------------------------------------------------------------------------
  144. //        • CActiveXView::InstantiateControl(Char8 **, Char8 **, Int16)
  145. // ---------------------------------------------------------------------------
  146. //    Instantiate a control when passed in embed style parameters
  147.  
  148. void
  149. CActiveXView::InstantiateControl(Char8 **inArgNames, Char8 **inArgValues, Int16 inArgCount)
  150. {
  151.     //    find the height and width parameters and size the pane accordingly
  152.     //    pass all parameters through by AddParam
  153.     Boolean8        HasWidth, HasHeight;
  154.     Int16            i;
  155.     PlatformPoint    Size;
  156.  
  157.     HasWidth = HasHeight = false;
  158.     for (i = 0; i < inArgCount; i++)
  159.     {
  160.         if (!HasWidth || !HasHeight)
  161.         {
  162.             Boolean8    IsWidth, IsHeight;
  163.             Str255        TempString;
  164.  
  165.             IsWidth = IsHeight = false;
  166.             CToPString(*(inArgNames+i), TempString);
  167.             if (!HasWidth)
  168.                 HasWidth = IsWidth = ::EqualString(TempString, "\pWIDTH", false, true);
  169.             if (!HasHeight && !IsWidth)
  170.                 HasHeight = IsHeight = ::EqualString(TempString, "\pHEIGHT", false, true);
  171.  
  172.             if (IsHeight || IsWidth)
  173.             {
  174.                 Int32    Temp;
  175.                 CToPString(*(inArgValues+i), TempString);
  176.                 ::StringToNum(TempString, &Temp);
  177.                 if (IsHeight)
  178.                     Size.v = Temp;
  179.                 else
  180.                     Size.h = Temp;
  181.             }
  182.         }
  183.  
  184.         this->AddParam(*(inArgNames+i), *(inArgValues+i));
  185.     }
  186.  
  187.     if (HasWidth && HasHeight)
  188.         RequestSizeChange(&Size);
  189.  
  190.     this->CreateControl(true);
  191.     this->SetContainerData((IContainer*) mDocumentP, this);
  192.  
  193.     //    add the site to the document
  194.     mDocumentP->AddSite(this);
  195.  
  196.     //    if the port exists, then tell the control about the drawing contexts
  197.     AttachPort(mDocumentP->GetPort() != NULL);
  198.  
  199.     //    create the streaming idle object
  200.     mStreamIdleP = new CIdle();
  201.     mStreamIdleP->StartIdling();
  202.  
  203.     Refresh();
  204. }
  205.  
  206.  
  207. // ---------------------------------------------------------------------------
  208. //        • CActiveXView::InstantiateControl(FSSpecPtr)
  209. // ---------------------------------------------------------------------------
  210. //    Instantiate a control when passed in a control's fsspec
  211.  
  212. void
  213. CActiveXView::InstantiateControl(FSSpecPtr inFileSpec)
  214. {
  215.     Boolean8        GotArgs = false;
  216.     Char8            **ArgNames;
  217.     Char8            **ArgValues;
  218.     Int16            ArgCount;
  219.     Ptr                ArgBufferP = NULL;
  220.     Int16            ResFile = ::FSpOpenResFile(inFileSpec, fsRdPerm);
  221.     StringHandle    StrHandle = NULL;
  222.  
  223.     if (::ResError() == noErr)
  224.     {
  225.         if ((StrHandle = ::GetString(128)) != NULL)
  226.         {
  227.             CArgumentParser    Parser;
  228.             Int16            i = 0;
  229.             Int16            Len = **StrHandle;
  230.  
  231.             while (++i <= Len)
  232.                 Parser.ProcessChar((*StrHandle)[i]);
  233.             Parser.ProcessChar('\0');
  234.             ::ReleaseResource(Handle(StrHandle));
  235.             GotArgs = Parser.GetArguments(&ArgBufferP,&ArgNames, &ArgValues, &ArgCount);
  236.         }
  237.         ::CloseResFile(ResFile);
  238.     }
  239.  
  240.     //    for now we need to close the res file before we instantiate the control
  241.     //    so that the resource fork chain is straight forward. I hope to fix this.
  242.  
  243.     if (GotArgs)
  244.     {
  245.         Handle    BaseURL;
  246.  
  247.         if ( (BaseURL = FileURLFromFileSpec(inFileSpec)) != NULL )
  248.         {
  249.             ::HLock(BaseURL);
  250.             SetBaseURL(*BaseURL);
  251.             ::HUnlock(BaseURL);
  252.             ::DisposeHandle(BaseURL);
  253.         }
  254.  
  255.         InstantiateControl(ArgNames, ArgValues, ArgCount);
  256.         ::DisposePtr(ArgBufferP);
  257.     }
  258.     else
  259.         ::SysBeep(0);
  260. }
  261.  
  262.  
  263. // ---------------------------------------------------------------------------
  264. //        • CActiveXView::RemoveControl()
  265. // ---------------------------------------------------------------------------
  266. //    Remove the Active X Control from the view
  267.  
  268. void CActiveXView::RemoveControl(void)
  269. {
  270.     this->RequestFocus(false, FocusSet(FullFocusSet));
  271.  
  272.     //    remove contexts from the control
  273.     {
  274.         Boolean8    FalseBool = false;
  275.         LView        *theViewP;
  276.         for (ArrayIndexT i = 1; mViewArrayP->FetchItemAt(i, (void*)&theViewP); i++)
  277.             UpdateDrawingContext(theViewP, RemoveContext);
  278.     }
  279.  
  280.     if (mControlP)
  281.     {
  282.         mDocumentP->RemoveSite(this);
  283.         this->DestroyControl();
  284.     }
  285.  
  286.     if (mMouseUpAttachmentP)
  287.     {
  288.         delete mMouseUpAttachmentP;
  289.         mMouseUpAttachmentP = NULL;
  290.     }
  291.  
  292.     //    no control to idle - if it was being idled
  293.     SetIdleTime(RemoveAllIdlers, NULL);
  294.  
  295.     mActiveView = this;
  296. }
  297.  
  298.  
  299. // ---------------------------------------------------------------------------
  300. //        • CActiveXView::UpdateDrawingContext
  301. // ---------------------------------------------------------------------------
  302. //    tell the control about a draw context change
  303.  
  304. void
  305. CActiveXView::UpdateDrawingContext(LView *inDrawView, ContextCommand inContextCommand)
  306. {
  307.     OnContextChange((UInt32) inDrawView->GetPaneID(), inContextCommand);
  308. }
  309.  
  310.  
  311. #ifdef MULTI_CONTEXT_TEST_APP
  312. // ---------------------------------------------------------------------------
  313. //        • CActiveXView::ClickInShadowView
  314. // ---------------------------------------------------------------------------
  315. //    tell acquire context which view is the 0th one
  316.  
  317. void
  318. CActiveXView::ClickInShadowView(CActiveXShadowView* inShadowView, SMouseDownEvent &inMouseDown)
  319. {
  320.     LView    *PrevActiveView = mActiveView;
  321.  
  322.     if ((mActiveView = inShadowView) == NULL)
  323.         mActiveView = this;
  324.  
  325.     if (PrevActiveView != mActiveView)
  326.     {
  327.         if (PrevActiveView)
  328.             UpdateDrawingContext(PrevActiveView, DeactivateContext);
  329.         UpdateDrawingContext(mActiveView, ActivateContext);
  330.     }
  331.  
  332.     HandleClick(inMouseDown);
  333. }
  334. #endif    //    MULTI_CONTEXT_TEST_APP
  335.  
  336.  
  337. // ---------------------------------------------------------------------------
  338. //        • CActiveXView::GetContextID
  339. // ---------------------------------------------------------------------------
  340. //    get an LView from the context id
  341.  
  342. Boolean8
  343. CActiveXView::GetContextID(Int32 inContextIndex, Uint32* outContextID)
  344. {
  345.     LView *theView = NULL;
  346.  
  347.     mViewArrayP->FetchItemAt(inContextIndex, &theView);
  348.  
  349.     if (theView)
  350.         *outContextID = theView->GetPaneID();
  351.  
  352.     return theView != NULL;
  353. }
  354.  
  355.  
  356. // ---------------------------------------------------------------------------
  357. //        • CActiveXView::GetDrawingViewFromID
  358. // ---------------------------------------------------------------------------
  359. //    get an LView from the context id
  360.  
  361. LView *
  362. CActiveXView::GetDrawingViewFromID( Uint32 inContextID )
  363. {
  364.     LView        *ResultDrawView = NULL;
  365.     LView        *theView = NULL;
  366.  
  367.     for (ArrayIndexT i = 1; !ResultDrawView && mViewArrayP->FetchItemAt(i, (void*)&theView); i++)
  368.     {
  369.         if (theView->GetPaneID() == inContextID)
  370.             ResultDrawView = theView;
  371.     }
  372.  
  373.     return ResultDrawView;
  374. }
  375.  
  376.  
  377. // ---------------------------------------------------------------------------
  378. //        • CActiveXView::AcquireContext
  379. // ---------------------------------------------------------------------------
  380. //    acquire the context of the view passed in
  381.  
  382. ErrorCode
  383. CActiveXView::AcquireContext(LView* inView, DrawContext* outContext)
  384. {
  385.     if (!inView || mHavePort || !mDocumentP->GetPort())
  386.     {
  387.         //  Don't allow the object to nest calls to GetDC
  388.         outContext->Port = NULL;
  389.         return E_FAIL;
  390.     }
  391.  
  392.     //    Save off the current port state
  393.     {
  394.         GrafPtr        SavePort, DrawingPort;
  395.  
  396.         ::GetPort(&SavePort);
  397.         inView->EstablishPort();
  398.         ::GetPort(&DrawingPort);
  399.         ::SetPort(SavePort);
  400.  
  401.         SavePortState(DrawingPort);
  402.     }
  403.  
  404.     //  Initialize the port to a known state.
  405.     inView->FocusDraw();
  406.     outContext->PortType = QDWindowPortType;
  407.     outContext->DrawAspect = DVASPECT_CONTENT;
  408.     outContext->ContextID = inView->GetPaneID();    //    context id's must be unique throughout the scope
  409.                                                     //    of the application. since the shadow views don't
  410.                                                     //    come and go we'll just use their pane ids as
  411.                                                     //    context ids. If we had dynamic split panes, then
  412.                                                     //    this wouldn't work.
  413.     outContext->ContainerRef = Uint32(inView);
  414.     outContext->Port = (GrafPtr) mDocumentP->GetPort();
  415.  
  416.     {
  417.         SDimension32    Size;
  418.         inView->GetImageSize(Size);
  419.         outContext->Location.top = outContext->Location.left = 0;
  420.         outContext->Location.bottom = Size.height;
  421.         outContext->Location.right = Size.width;
  422.     }
  423. //    inView->CalcLocalFrameRect(outContext->Location);
  424. //    ::OffsetRect(&outContext->Location, -outContext->Location.left, -outContext->Location.top);
  425.  
  426.     mHavePort = true;
  427.  
  428.     return S_OK;
  429. }
  430.  
  431.  
  432. // ---------------------------------------------------------------------------
  433. //        • CActiveXView::DrawSelf
  434. // ---------------------------------------------------------------------------
  435. //    Draw the control
  436.  
  437. void
  438. CActiveXView::DrawSelf()
  439. {
  440.     Boolean8    FailedToDraw = true;
  441.  
  442.     if (mControlP)
  443.     {
  444.         DrawContext    theDrawContext = {BeginPortType};
  445.  
  446.         if (mPendingViewsP)
  447.             AttachPort(true);
  448.  
  449.         if (mContextDirty)
  450.         {
  451.             UpdateDrawingContext(this, UpdateContext);
  452.             mContextDirty = false;
  453.         }
  454.  
  455.         if (this->AcquireContext(this, &theDrawContext) == S_OK)
  456.         {
  457.             mControlP->Draw(&theDrawContext);
  458.             FailedToDraw = false;
  459.             this->ReleaseContext(&theDrawContext);
  460.         }
  461.     }
  462.  
  463.     if (FailedToDraw)
  464.     {
  465.         Rect        Frame;
  466.         StringPtr    ErrorMessage = "\pDrop a control here!";
  467.  
  468.         CalcLocalFrameRect(Frame);
  469.         ::PenNormal();
  470.         ::FillRect(&Frame, &UQDGlobals::GetQDGlobals()->ltGray);
  471.  
  472.         ::TextFace(bold);
  473.         ::TextFont(0);
  474.         ::TextSize(12);
  475.         ::TETextBox(ErrorMessage + 1, *ErrorMessage, &Frame, 1);
  476.     }
  477. }
  478.  
  479.  
  480. // ---------------------------------------------------------------------------
  481. //        • CActiveXView::DoEvent
  482. // ---------------------------------------------------------------------------
  483. //    Pass events to Active X
  484.  
  485. void
  486. CActiveXView::DoEvent(EventRecord *Event, Boolean *PassEventUp, Boolean *RemoveAttachment)
  487. {
  488.     *RemoveAttachment = true;
  489.     *PassEventUp = true;
  490.  
  491.     if (mControlP)
  492.     {
  493.         if (Event->what != mouseUp)
  494.             *RemoveAttachment = false;
  495.         else
  496.             mControlP->DoMouse(MouseUp, Event);
  497.     }
  498. }
  499.  
  500.  
  501. #ifdef MULTI_CONTEXT_TEST_APP
  502. // ---------------------------------------------------------------------------
  503. //        • CActiveXView::AddShadowView
  504. // ---------------------------------------------------------------------------
  505. //    add a shadow view to the shadow view list
  506.  
  507. void
  508. CActiveXView::AddShadowView(CActiveXShadowView *inShadowView)
  509. {
  510.     Boolean8    FalseBool = false;
  511.  
  512.     mViewArrayP->InsertItemsAt(1, LArray::index_Last, (void*)&inShadowView);
  513.     UpdateDrawingContext(inShadowView, AddContext);
  514. }
  515.  
  516.  
  517. // ---------------------------------------------------------------------------
  518. //        • CActiveXView::RemoveShadowView
  519. // ---------------------------------------------------------------------------
  520. //    add a shadow view to the shadow view list
  521.  
  522. void
  523. CActiveXView::RemoveShadowView(CActiveXShadowView *inShadowView)
  524. {
  525.     long        ContextIndex = mViewArrayP->FetchIndexOf(&inShadowView);
  526.  
  527.     UpdateDrawingContext(inShadowView, RemoveContext);
  528.  
  529.     if ( mActiveView == inShadowView )
  530.         mActiveView = this;
  531.  
  532.     mViewArrayP->RemoveItemsAt(1, ContextIndex);
  533. }
  534.  
  535.  
  536. // ---------------------------------------------------------------------------
  537. //        • CActiveXView::DrawShadowView
  538. // ---------------------------------------------------------------------------
  539. //    add a shadow view to the shadow view list
  540.  
  541. void
  542. CActiveXView::DrawShadowView(CActiveXShadowView *inShadowView, Boolean8 inUpdateContext)
  543. {
  544.     Boolean        FailedToDraw = true;
  545.     DrawContext    theDrawContext = {BeginPortType};
  546.  
  547.     if (mControlP)
  548.     {
  549.         if (mPendingViewsP)
  550.             AttachPort(true);
  551.  
  552.         if (inUpdateContext)
  553.             UpdateDrawingContext(inShadowView, UpdateContext);
  554.  
  555.         if (this->AcquireContext(inShadowView, &theDrawContext) == S_OK)
  556.         {
  557.             mControlP->Draw(&theDrawContext);
  558.             FailedToDraw = false;
  559.             this->ReleaseContext(&theDrawContext);
  560.         }
  561.     }
  562.  
  563.     if (FailedToDraw)
  564.     {
  565.         Rect    Frame;
  566.  
  567.         CalcLocalFrameRect(Frame);
  568.         ::PenNormal();
  569.         ::FillRect(&Frame, &UQDGlobals::GetQDGlobals()->ltGray);
  570.         ::FrameRect(&Frame);
  571.     }
  572. }
  573. #endif    //    MULTI_CONTEXT_TEST_APP
  574.  
  575.  
  576. // ---------------------------------------------------------------------------
  577. //        • CActiveXView::HandleClick
  578. // ---------------------------------------------------------------------------
  579. //    pass the event to the control and do local stuff
  580.  
  581. void
  582. CActiveXView::HandleClick(SMouseDownEvent &inMouseDown)
  583. {
  584.     if (mControlP)
  585.     {
  586.         mControlP->DoMouse(MouseDown, &inMouseDown.macEvent);
  587.         EventRecord    TempEvent;
  588.  
  589.         //    now make the main event loop tell us about the mouse up
  590.         if (::StillDown() || (::EventAvail(mDownMask | mUpMask, &TempEvent) && TempEvent.what == mouseUp))
  591.         {
  592.             LCommander            *SuperSuper = this;
  593.             LCommander            *Super;
  594.  
  595.             if (!mMouseUpAttachmentP)
  596.                 mMouseUpAttachmentP = new CActiveXAttachment(this);
  597.             else if (mMouseUpAttachmentP->GetOwnerHost())
  598.                 DebugStr("\pWhat - it is already in use!");
  599.  
  600.             do
  601.             {
  602.                 Super = SuperSuper;
  603.                 SuperSuper = Super->GetSuperCommander();
  604.             }
  605.             while (SuperSuper);
  606.  
  607.             Super->AddAttachment(mMouseUpAttachmentP, false);
  608.         }
  609.     }
  610.     else
  611.         //    clicked in an empty pane - maybe wanting to designate it for insert commands
  612.         BeTarget();
  613. }
  614.  
  615.  
  616. // ---------------------------------------------------------------------------
  617. //        • CActiveXView::AttachPort
  618. // ---------------------------------------------------------------------------
  619. //    pass the event to the control and do local stuff
  620.  
  621. void
  622. CActiveXView::AttachPort(Boolean inHasPort)
  623. {
  624.     if (inHasPort)
  625.     {
  626.         LView    *theView;
  627.  
  628.         if (mPendingViewsP)
  629.         {
  630.             for (ArrayIndexT i = 1; mPendingViewsP->FetchItemAt(i, (void*)&theView); i++)
  631.                 UpdateDrawingContext(theView, AddContext);
  632.             delete mPendingViewsP;
  633.             mPendingViewsP = NULL;
  634.         }
  635.         else
  636.             for (ArrayIndexT i = 1; mViewArrayP->FetchItemAt(i, (void*)&theView); i++)
  637.                 UpdateDrawingContext(theView, AddContext);
  638.  
  639.         UpdateDrawingContext(mActiveView, ActivateContext);
  640.     }
  641.     else
  642.     {
  643.         LView    *theView;
  644.  
  645.         if (!mPendingViewsP)
  646.             mPendingViewsP = new LArray(sizeof(LView *));
  647.  
  648.         for (ArrayIndexT i = 1; mViewArrayP->FetchItemAt(i, (void*)&theView); i++)
  649.             mPendingViewsP->InsertItemsAt(1, i, (void*)&theView);
  650.     }
  651. }
  652.  
  653.  
  654. #pragma mark === CActiveXView::LView ===
  655.  
  656. // ---------------------------------------------------------------------------
  657. //        • CActiveXView::LView::Click
  658. // ---------------------------------------------------------------------------
  659. //    Log self as the active draw context, and pass through the click
  660.  
  661. void
  662. CActiveXView::Click(SMouseDownEvent &inMouseDown)
  663. {
  664.     LView    *PrevActiveView = mActiveView;
  665.  
  666.     mActiveView = this;
  667.  
  668.     if (PrevActiveView != mActiveView)
  669.     {
  670.         if (PrevActiveView)
  671.             UpdateDrawingContext(PrevActiveView, DeactivateContext);
  672.         UpdateDrawingContext(mActiveView, ActivateContext);
  673.     }
  674.  
  675.     HandleClick(inMouseDown);
  676. }
  677.  
  678.  
  679. // ---------------------------------------------------------------------------
  680. //        • CActiveXView::LView::ResizeFrameBy
  681. // ---------------------------------------------------------------------------
  682. //    Log self as the active draw context, and pass through the click
  683.  
  684. void
  685. CActiveXView::ResizeFrameBy(Int16 inWidthDelta, Int16 inHeightDelta, Boolean inRefresh)
  686. {
  687.     mContextDirty = true;
  688.     LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  689. }
  690.  
  691.  
  692. // ---------------------------------------------------------------------------
  693. //        • CActiveXView::LView::MoveBy
  694. // ---------------------------------------------------------------------------
  695. //    Log self as the active draw context, and pass through the click
  696.  
  697. void
  698. CActiveXView::MoveBy(Int32 inHorizDelta, Int32 inVertDelta, Boolean inRefresh)
  699. {
  700.     mContextDirty = true;
  701.     LView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
  702. }
  703.  
  704.  
  705. // ---------------------------------------------------------------------------
  706. //        • CActiveXView::LView::AdaptToNewSurroundings
  707. // ---------------------------------------------------------------------------
  708. //    Log self as the active draw context, and pass through the click
  709.  
  710. void
  711. CActiveXView::AdaptToNewSurroundings(void)
  712. {
  713.     mContextDirty = true;
  714.     LView::AdaptToNewSurroundings();
  715. }
  716.  
  717.  
  718. // ---------------------------------------------------------------------------
  719. //        • CActiveXView::LView::AdaptToSuperFrameSize
  720. // ---------------------------------------------------------------------------
  721. //    Log self as the active draw context, and pass through the click
  722.  
  723. void
  724. CActiveXView::AdaptToSuperFrameSize(Int32 inSurrWidthDelta, Int32 inSurrHeightDelta, Boolean inRefresh)
  725. {
  726.     mContextDirty = true;
  727.     LView::AdaptToSuperFrameSize(inSurrWidthDelta, inSurrHeightDelta, inRefresh);
  728. }
  729.  
  730.  
  731. // ---------------------------------------------------------------------------
  732. //        • CActiveXView::LView::ScrollImageBy
  733. // ---------------------------------------------------------------------------
  734. //    Log self as the active draw context, and pass through the click
  735.  
  736. void
  737. CActiveXView::ScrollImageBy(Int32 inLeftDelta, Int32 inTopDelta, Boolean inRefresh)
  738. {
  739.     mContextDirty = true;
  740.     LView::ScrollImageBy(inLeftDelta, inTopDelta, inRefresh);
  741. }
  742.  
  743.  
  744. // ---------------------------------------------------------------------------
  745. //        • CActiveXView::LView::ResizeImageBy
  746. // ---------------------------------------------------------------------------
  747. //    Log self as the active draw context, and pass through the click
  748.  
  749. void
  750. CActiveXView::ResizeImageBy(Int32 inWidthDelta, Int32 inHeightDelta, Boolean inRefresh)
  751. {
  752.     mContextDirty = true;
  753.     LView::ResizeImageBy(inWidthDelta, inHeightDelta, inRefresh);
  754. }
  755.  
  756.  
  757. #pragma mark === CActiveXView::LCommander ===
  758.  
  759. // ---------------------------------------------------------------------------------
  760. //        • FindCommandStatus
  761. // ---------------------------------------------------------------------------------
  762.  
  763. void
  764. CActiveXView::FindCommandStatus(
  765.     CommandT    inCommand,
  766.     Boolean        &outEnabled,
  767.     Boolean        &outUsesMark,
  768.     Char16        &outMark,
  769.     Str255        outName )
  770. {
  771.     if ( inCommand ==  cmd_Insert)
  772.         outEnabled = true;
  773.     else
  774.         LCommander::FindCommandStatus( inCommand, outEnabled, outUsesMark, outMark, outName );
  775. }
  776.  
  777.  
  778. // ---------------------------------------------------------------------------------
  779. //        • CActiveXView::ObeyCommand
  780. // ---------------------------------------------------------------------------------
  781.  
  782. Boolean
  783. CActiveXView::ObeyCommand(CommandT inCommand, void *ioParam)
  784. {
  785. #pragma unused (ioParam)
  786.     Boolean        cmdHandled = false;
  787.  
  788.     if (inCommand == cmd_Insert)
  789.     {
  790.         StandardFileReply    Reply;
  791.         SFTypeList            TypeList = { 'shlb' };
  792.  
  793.         ::StandardGetFile(NULL, 1, TypeList, &Reply);
  794.         if (Reply.sfGood)
  795.         {
  796.             if (mControlP)
  797.                 RemoveControl();
  798.             InstantiateControl(&Reply.sfFile);
  799.         }
  800.         cmdHandled = true;
  801.     }
  802.     else
  803.         cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
  804.  
  805.     return cmdHandled;
  806. }
  807.  
  808.  
  809. // ---------------------------------------------------------------------------
  810. //        • CActiveXView::BeTarget
  811. // ---------------------------------------------------------------------------
  812. //    ActiveX view is becoming the Target
  813.  
  814. void
  815. CActiveXView::BeTarget()
  816. {
  817.     if (!mInRequestFocus && mControlP)
  818.     {
  819.         //    if the app has gotten so far as to make us the target then there is a window
  820.         if (mPendingViewsP)
  821.             AttachPort(true);
  822.  
  823.         this->RequestFocus( true, KeyboardFocus );
  824.         if (SetFocus(TakeNextCommand, KeyboardFocus) != S_OK)
  825.         {
  826.             LCommander    *NewTarget = GetLatentSub();
  827.             this->RequestFocus( false, KeyboardFocus );
  828.             if (NewTarget)
  829.                 SwitchTarget(NewTarget);
  830.         }
  831.     }
  832. }
  833.  
  834.  
  835. // ---------------------------------------------------------------------------
  836. //        • CActiveXView::DontBeTarget
  837. // ---------------------------------------------------------------------------
  838. //    TextEdit is no longer the Target
  839. //
  840. //    Remove TextEdit from IdleQueue
  841.  
  842. void
  843. CActiveXView::DontBeTarget()
  844. {
  845.     if (!mInRequestFocus)
  846.     {
  847.         this->SetFocus(ReleaseCommand, KeyboardFocus);
  848.         this->RequestFocus( false, KeyboardFocus );
  849.     }
  850. }
  851.  
  852.  
  853. // ---------------------------------------------------------------------------
  854. //        • CActiveXView::HandleKeyPress
  855. // ---------------------------------------------------------------------------
  856. //    Pass key events to Active X
  857.  
  858. Boolean
  859. CActiveXView::HandleKeyPress(const EventRecord& inKeyEvent)
  860. {
  861.     if (mControlP)
  862.     {
  863.         //    this isn't really what tab would mean, cycle through the different
  864.         //    contexts, it should really advance the keyboard focus, but I needed
  865.         //    a way to test the activate/deactivate code which didn't move the
  866.         //    selection point in the text edit control
  867.         if ((inKeyEvent.message & charCodeMask) == '\t')
  868.         {
  869.             ArrayIndexT    ActiveViewIndex;
  870.             LView        *PrevActiveView = mActiveView;
  871.  
  872.             ActiveViewIndex = mViewArrayP->FetchIndexOf((void*)&PrevActiveView) + 1;
  873.  
  874.             if (!mViewArrayP->FetchItemAt(ActiveViewIndex, (void*)&mActiveView))
  875.                 mViewArrayP->FetchItemAt(1, (void*)&mActiveView);
  876.  
  877.             if (PrevActiveView != mActiveView)
  878.             {
  879.                 if (PrevActiveView)
  880.                     UpdateDrawingContext(PrevActiveView, DeactivateContext);
  881.                 UpdateDrawingContext(mActiveView, ActivateContext);
  882.             }
  883.  
  884.             return true;
  885.         }
  886.         else
  887.         {
  888.             KeyEventType    theKeyET;
  889.             Point            theLocation = inKeyEvent.where;
  890.             
  891.             ::GlobalToLocal(&theLocation);
  892.             
  893.             if (inKeyEvent.what == autoKey)
  894.                 theKeyET = AutoKey;
  895.             else
  896.                 theKeyET = KeyDown;
  897.                 
  898.             return mControlP->DoKey(theKeyET, (inKeyEvent.message & charCodeMask), (EventRecord*) &inKeyEvent);
  899.         }
  900.     }
  901.     else
  902.         return false;
  903. }
  904.  
  905.  
  906. #pragma mark === CActiveXView::LDragAndDrop ===
  907.  
  908. // ---------------------------------------------------------------------------
  909. //        • CActiveXView::LDragAndDrop::ItemIsAcceptable
  910. // ---------------------------------------------------------------------------
  911. //    tell the control about a draw context change
  912.  
  913. Boolean
  914. CActiveXView::ItemIsAcceptable( DragReference inDragRef, ItemReference inItemRef )
  915. {
  916.     FlavorFlags    theFlags;
  917.     if (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags) == noErr)
  918.     {
  919.         HFSFlavor    FSData;
  920.         Size        DataSize = sizeof(HFSFlavor);
  921.  
  922.         if (::GetFlavorData( inDragRef, inItemRef, flavorTypeHFS, &FSData, &DataSize, 0L) == noErr
  923.             && FSData.fileType == 'shlb' && FSData.fileCreator == 'cfmg')
  924.             return true;
  925.     }
  926.  
  927.     return false;
  928. }
  929.  
  930.  
  931. // ---------------------------------------------------------------------------
  932. //        • CActiveXView::LDragAndDrop::ReceiveDragItem
  933. // ---------------------------------------------------------------------------
  934. //    tell the control about a draw context change
  935.  
  936. void
  937. CActiveXView::ReceiveDragItem( DragReference inDragRef, DragAttributes,
  938.                             ItemReference inItemRef, Rect &)
  939. {
  940.     HFSFlavor    FSData;
  941.     Size        DataSize = sizeof(HFSFlavor);
  942.  
  943.     if (::GetFlavorData( inDragRef, inItemRef, flavorTypeHFS, &FSData, &DataSize, 0L ) == noErr)
  944.     {
  945.         if (mControlP)
  946.             RemoveControl();
  947.         InstantiateControl(&FSData.fileSpec);
  948.     }
  949. }
  950.  
  951.  
  952. #pragma mark === CActiveXView::CBaseSite::IContainerSite ===
  953.  
  954.  
  955. // ---------------------------------------------------------------------------------
  956. //        • CActiveXView::CBaseSite::IContainerSite::AcquireContextByID
  957. // ---------------------------------------------------------------------------------
  958.  
  959. STDMETHODIMP
  960. CActiveXView::AcquireContext(Uint32 inContextID, DrawContext* outContext)
  961. {
  962.     LView    *theDrawView;
  963.  
  964.     theDrawView = GetDrawingViewFromID(inContextID);
  965.         
  966.     return AcquireContext(theDrawView, outContext);
  967. }
  968.  
  969.  
  970. // ---------------------------------------------------------------------------------
  971. //        • CActiveXView::CBaseSite::IContainerSite::ReleaseContext
  972. // ---------------------------------------------------------------------------------
  973.  
  974. STDMETHODIMP
  975. CActiveXView::ReleaseContext(DrawContext* inContext)
  976. {
  977.     ErrorCode    Result = CXSite::ReleaseContext(inContext);
  978.     LView::OutOfFocus(NULL);
  979.     return Result;
  980. }
  981.  
  982.  
  983. // ---------------------------------------------------------------------------------
  984. //        • CActiveXView::CBaseSite::IContainerSite::RequestFocus
  985. // ---------------------------------------------------------------------------------
  986.  
  987. STDMETHODIMP
  988. CActiveXView::RequestFocus (Boolean8 inAcquire, FocusSet inFocus)
  989. {
  990.     // Pass this on to the document
  991.     mInRequestFocus = true;
  992.     mDocumentP->RequestFocus(this, inAcquire, inFocus);
  993.     mInRequestFocus = false;
  994.  
  995.     return S_OK;
  996. }
  997.  
  998.  
  999. // ---------------------------------------------------------------------------------
  1000. //        • CActiveXView::CBaseSite::IContainerSite::RequestSizeChange
  1001. // ---------------------------------------------------------------------------------
  1002.  
  1003. STDMETHODIMP
  1004. CActiveXView::RequestSizeChange(PlatformPoint* ioSize)
  1005. {
  1006.     ArrayIndexT            i = 1;
  1007.     ErrorCode            Result = S_OK;
  1008.     LView*                ControlView;
  1009.  
  1010.     while (mViewArrayP->FetchItemAt(i++, &ControlView))
  1011.         ControlView->ResizeImageTo(ioSize->h, ioSize->v, false);
  1012.  
  1013.     return Result;
  1014. }
  1015.  
  1016.  
  1017. // ---------------------------------------------------------------------------------
  1018. //        • CActiveXView::CBaseSite::IContainerSite::SetIdleTime
  1019. // ---------------------------------------------------------------------------------
  1020.  
  1021. STDMETHODIMP
  1022. CActiveXView::SetIdleTime (Int32 WaitTicks, Uint32 IdleRefCon)
  1023. {
  1024.     ErrorCode            Result = CXSite::SetIdleTime(WaitTicks, IdleRefCon);
  1025.     CActiveXPeriodical::UpdatePeriodical();
  1026.     return Result;
  1027. }
  1028.  
  1029.  
  1030. #pragma mark === CActiveXAttachment ===
  1031.  
  1032. // ---------------------------------------------------------------------------
  1033. //        • CActiveXAttachment
  1034. // ---------------------------------------------------------------------------
  1035. //    Constructor for ActiveX Attachment
  1036.  
  1037.  
  1038. CActiveXAttachment::CActiveXAttachment( CActiveXView *inActiveXView )
  1039.         : LAttachment( msg_Event ), mActiveXView( inActiveXView )
  1040. {
  1041. }
  1042.  
  1043.  
  1044. // ---------------------------------------------------------------------------
  1045. //        • CActiveXAttachment::~CActivevXAttachment
  1046. // ---------------------------------------------------------------------------
  1047. //    Destructor for ActiveX Attachment
  1048.  
  1049. CActiveXAttachment::~CActiveXAttachment()
  1050. {
  1051.     if (mOwnerHost)
  1052.         mOwnerHost->RemoveAttachment(this);
  1053. }
  1054.  
  1055.  
  1056. // ---------------------------------------------------------------------------
  1057. //        • CActiveXAttachment::ExecuteSelf
  1058. // ---------------------------------------------------------------------------
  1059. //    Actually do the attachment thing
  1060.  
  1061. void CActiveXAttachment::ExecuteSelf( MessageT inMessage, void *ioParam )
  1062. {
  1063.     Boolean        Remove = false;
  1064.  
  1065.     mExecuteHost = true;
  1066.  
  1067.     if (inMessage == msg_Event)
  1068.         mActiveXView->DoEvent((EventRecord *)ioParam, &mExecuteHost, &Remove);
  1069.  
  1070.     if (Remove)
  1071.         mOwnerHost->RemoveAttachment(this);
  1072. }
  1073.  
  1074.  
  1075. // ---------------------------------------------------------------------------
  1076. //        • CToPString [ static ]
  1077. // ---------------------------------------------------------------------------
  1078. //    convert a c string to a pascal string
  1079.  
  1080. void CToPString(Char8* CPtr, StringPtr PStr)
  1081. {
  1082.     Char8*    p1 = CPtr;
  1083.     Char8*    p2 = (Char8*) PStr + 1;
  1084.     Int16    i = 255;
  1085.  
  1086.     while (i-- && (*p2++ = *p1++) != 0)
  1087.         ;
  1088.  
  1089.     *PStr = p1 - CPtr - 1;
  1090. }
  1091.